﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Linq;

using QSHC.LibrarySL.MVVM;
using QSHC.QSchedule.Web.Models;
using QSHC.QSchedule.Silverlight.Helpers;
using QSHC.QSchedule.Web.Services;
using System.ServiceModel.DomainServices.Client;
using QSHC.QSchedule.Silverlight.Views.Windows;

namespace QSHC.QSchedule.Silverlight.ViewModels
{
    public class PhysicianAbsentViewModel : ViewModelBase
    {
        private QScheduleDomainContext _dc = new QScheduleDomainContext();

        #region Properties

        #region Property Physicians
        private IEnumerable<Employee> _physicians;
        public IEnumerable<Employee> Physicians
        {
            get { return _physicians; }
            set
            {
                if (_physicians != value)
                {
                    _physicians = value;
                    OnPropertyChanged(() => Physicians);
                }
            }
        }
        #endregion

        #region Property SelectedPhysician
        private Employee _selectedPhysician;
        public Employee SelectedPhysician
        {
            get { return _selectedPhysician; }
            set
            {
                if (_selectedPhysician != value)
                {
                    _selectedPhysician = value;
                    OnPropertyChanged(() => SelectedPhysician);

                    AddCommand.OnCanExecuteChanged();
                    LoadPhysicianAbsents();
                }
            }
        }
        #endregion

        #region Property Reason
        private string _reason;
        public string Reason
        {
            get { return _reason; }
            set
            {
                if (_reason != value)
                {
                    _reason = value;
                    OnPropertyChanged(() => Reason);

                    AddCommand.OnCanExecuteChanged();
                }
            }
        }
        #endregion

        #region Property Services
        private IEnumerable<Service> _services;
        public IEnumerable<Service> Services
        {
            get { return _services; }
            set
            {
                if (_services != value)
                {
                    _services = value;
                    OnPropertyChanged(() => Services);
                }
            }
        }
        #endregion

        #region Property SelectedService
        private Service _selectedService;
        public Service SelectedService
        {
            get { return _selectedService; }
            set
            {
                if (_selectedService != value)
                {
                    _selectedService = value;
                    OnPropertyChanged(() => SelectedService);

                    AddCommand.OnCanExecuteChanged();
                }
            }
        }
        #endregion

        #region Property BeginDate
        private DateTime? _beginDate;
        public DateTime? BeginDate
        {
            get { return _beginDate; }
            set
            {
                if (_beginDate != value)
                {
                    _beginDate = value;
                    OnPropertyChanged(() => BeginDate);

                    AddCommand.OnCanExecuteChanged();
                }
            }
        }
        #endregion

        #region Property EndDate
        private DateTime? _endDate;
        public DateTime? EndDate
        {
            get { return _endDate; }
            set
            {
                if (_endDate != value)
                {
                    _endDate = value;
                    OnPropertyChanged(() => EndDate);
                }
            }
        }
        #endregion

        #region Property PhysicianAbsents
        private IEnumerable<PhysicianAbsent> _physicianAbsents;
        public IEnumerable<PhysicianAbsent> PhysicianAbsents
        {
            get { return _physicianAbsents; }
            set
            {
                if (_physicianAbsents != value)
                {
                    _physicianAbsents = value;
                    OnPropertyChanged(() => PhysicianAbsents);
                }
            }
        }
        #endregion

        #region Property SelectedPhysicianAbsent
        private PhysicianAbsent _physicianAbsent;
        public PhysicianAbsent SelectedPhysicianAbsent
        {
            get { return _physicianAbsent; }
            set
            {
                if (_physicianAbsent != value)
                {
                    _physicianAbsent = value;
                    OnPropertyChanged(() => SelectedPhysicianAbsent);

                    DeleteCommand.OnCanExecuteChanged();
                }
            }
        }
        #endregion

        #endregion

        #region Commands

        #region AddCommand
        private ViewModelCommand _addCommand = null;
        public ViewModelCommand AddCommand
        {
            get
            {
                if (_addCommand == null)
                    _addCommand = new ViewModelCommand(p => Add(p), p => CanAdd);
                return _addCommand;
            }
        }

        private void Add(object obj)
        {
            AddPhysicianAbsent();
        }

        public bool CanAdd
        {
            get { return SelectedPhysician != null &&
                         !string.IsNullOrWhiteSpace(Reason) &&
                         SelectedService != null &&
                         BeginDate != null; }
        }
        #endregion

        #region DeleteCommand
        private ViewModelCommand _deleteCommand = null;
        public ViewModelCommand DeleteCommand
        {
            get
            {
                if (_deleteCommand == null)
                    _deleteCommand = new ViewModelCommand(p => Delete(p), p => CanDelete);
                return _deleteCommand;
            }
        }

        private void Delete(object obj)
        {
            var result = MessageBox.Show("คุณแน่ใจที่จะลบวันลานี้", "คำเตือน", MessageBoxButton.OKCancel);

            if (result == MessageBoxResult.OK)
                DeletePhysicianAbsent();
        }

        public bool CanDelete
        {
            get { return SelectedPhysicianAbsent != null; }
        }
        #endregion

        #endregion

        public PhysicianAbsentViewModel()
        {
            if (!IsInDesignModeStatic)
            {
                Physicians = EmployeeHelper.Physicians;

                var lo = _dc.Load(_dc.GetServicesQuery());
                lo.Completed += (s, e) =>
                {
                    var services = new List<Service>();
                    services.Add(new Service { ServiceID = 0, Name = "--ทั้งหมด--" });
                    services.AddRange(lo.Entities);

                    Services = services;
                    Reset();
                };
            }
        }

        private void Reset()
        {
            Reason = string.Empty;
            SelectedService = Services.First();
            BeginDate = DateTime.Today;
            EndDate = DateTime.Today;
        }

        private void LoadPhysicianAbsents()
        {
            var lo = _dc.Load(_dc.GetPhysicianAbsentsByPhysicianCodeQuery(SelectedPhysician.EmployeeCode));
            lo.Completed += (s, e) =>
            {
                PhysicianAbsents = lo.Entities;
            };
        }

        private void AddPhysicianAbsent()
        {
            var physicianAbsent = new PhysicianAbsent
            {
                Physician = SelectedPhysician.EmployeeCode,
                Reason = Reason,
                BeginDate = BeginDate.Value,
                EndDate = EndDate,
                //EndDate = BeginDate.Value == EndDate.Value || EndDate == null ? null : EndDate,
            };

            if (SelectedService.ServiceID != 0)
                physicianAbsent.ServiceID = SelectedService.ServiceID;
            else
                physicianAbsent.ServiceID = null;

            var log = new LogPhysicianAbsent
            {
                EmployeeCode = EmployeeHelper.LoggedEmployee,
                LogDateTime = DateTime.Now,
                Action = 1, // Create
                PhysicianAbsent = physicianAbsent,
            };

            _dc.PhysicianAbsents.Add(physicianAbsent);
            _dc.SubmitChanges().Completed += (s, e) =>
            {
                //MessageBox.Show("บันทึกแล้ว");

                LoadPhysicianAbsents();
                GetCurrentDateAllPatient(() => 
                    {

                        var vm = new AppointmentListViewModel(BeginDate.Value, EndDate, null);
                        var win = new AppointmentListWindow();
                        win.appointmentList.DataContext = vm;

                        win.Show();
                        win.Unloaded += (sender, args) =>
                        {

                        };
                        
                        
                        
                        //Reset();
                    });
            };
        }

        private void DeletePhysicianAbsent()
        {
            SelectedPhysicianAbsent.IsDeleted = true;

            var log = new LogPhysicianAbsent
            {
                EmployeeCode = EmployeeHelper.LoggedEmployee,
                LogDateTime = DateTime.Now,
                Action = 4, // Delete
                PhysicianAbsent = SelectedPhysicianAbsent,
            };

            _dc.SubmitChanges().Completed += (s, e) =>
            {
                Reset();
                LoadPhysicianAbsents();
            };
        }

        //Daeng
        private void GetCurrentDateAllPatient(Action callback)
        {
            var qry = from p in _dc.GetAppointmentsQuery()
                      where p.AppointmentDate >= BeginDate && (EndDate != null ? p.AppointmentDate <= EndDate.Value : true)
                      select p;

            if (SelectedService.ServiceID != 0)
                qry = qry.Where(p => p.ServiceID == SelectedService.ServiceID);

            var lo = _dc.Load(qry);
            lo.Completed += (s, e) =>
            {
                if (lo.Entities.Count() > 0)
                {
                    callback.Invoke();
                }
            };
        }
    }
}
